module text_display
    use ttt_board
    implicit none
    private
    public display, get_move, display_module_initialize, &
        display_module_finalize

    interface display
        module procedure display_message, display_board
    end interface display

contains

    subroutine display_module_initialize
    call display("Welcome to Tic-Tac-Toe.")
    call display("Special moves: -n, 0 to undo n moves.")
    call display("                0, 0 to exit.")
    end subroutine display_module_initialize

    subroutine display_module_finalize
    call display("Thanks for playing Tic-Tac-Toe.")
    end subroutine display_module_finalize

    subroutine display_message(c)
    character(len=*) c
    write(6, *) c
    end subroutine display_message

    subroutine display_board(b)
    type(board), intent(in):: b
    character s(size(b%spaces,1), size(b%spaces,2))
    character*80 f1,f2
    integer i
    character:: labels(max(size(s,1), size(s,2))) 

    do i = 1, size(labels)
        write(labels(i), "(i1)") i
    enddo
    s = as_string(b)
    write(f1, "(a,i5,a)") "(2x,", size(s,2), "(a1, 1x))"
    write(f2, "(a,i5,a)") "(a, x,", size(s,2), "(a1, 1x))"
    !write(6,*) f1
    !write(6,*) f2
    write(6,f1) (labels(i), i=1, size(s,2))
    do i = 1, size(s,1)
        write(6,f2) labels(i), s(i,:)
    enddo

    end subroutine display_board

    function get_move(b) result(m)
    type(board), intent(in):: b
    type(move_spec) m
	type(piece), pointer:: available_pieces(:)
    type(piece):: opposition
    integer i, j, i1, j1
    integer wt, wt1
    real factor

	available_pieces => holdings(b%to_move)
	m%p= available_pieces(1)   ! TTT only has one piece to choose from
    m%code = move_command
    !if only one move possible, make it.
    if(open_positions(b) == 1) then
        do i = 1, size(b%spaces, 1)
            do j = 1, size(b%spaces, 2)
                if(is_empty(b%spaces(i,j))) then
                    m%x = i
                    m%y = j
                    return
                endif
            enddo
        enddo
    endif
    if(controller(b%to_move) == human_controller) then
        call display(b)
        write(6, *) "It is ", as_string(mover(b)), "'s turn to move."
        write(6, *) "Enter x, y, (0,0) to quit: "
        read(5, *) m%x, m%y
        if(m%x < 0) m%code = undo_command
        if(m%x == 0 .and. m%y == 0) m%code = quit_command
    else
        available_pieces => holdings(opponent(b%to_move))
        opposition = available_pieces(1)
        ! If we can win, do it.
        do i = 1, size(b%spaces, 1)
            do j = 1, size(b%spaces, 2)
               if(legal_move(b, m%p, i, j)) then
                    if(is_winner(b, m%p, i, j)) then
                        m%x = i
                        m%y = j
                        return
                    endif
               endif
            enddo
        enddo
        wt1 = -1
        i1 = 0
        j1 = 0
        do i = 1, size(b%spaces, 1)
            do j = 1, size(b%spaces, 2)
! Prevent immediate loss first, otherwise make educated guess.
                if(legal_move(b, opposition, i, j)) then
                    if(is_winner(b, opposition, i, j)) then
                        m%x = i
                        m%y = j
                        return
                    endif
                endif
                if(legal_move(b, m%p, i, j)) then
                    wt = 100 - (5*((i-2)**2 + (j-2)**2) + modulo(i+j,2))
                    call random_number(factor)
                    wt = wt * (1 + factor/3.0)
                    if(wt > wt1) then
                        i1 = i
                        j1 = j
                        wt1 = wt
                    endif
                endif
            enddo
        enddo
        m%x = i1
        m%y = j1
    endif
    end function get_move
    
end module text_display